package org.axed.user.client.axessory;

import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import java.util.Stack;
import java.util.Vector;
import org.axed.user.client.AxedListener;
import org.axed.user.client.AxedArea;
import org.axed.user.client.AxedEvent;
import org.axed.user.client.DOM;
import org.axed.user.client.UndoBuffer;
import org.axed.user.client.UndoManager;

/**
 * The undoviewer is a table that shows the actions in events.
 */
public class UndoViewer extends FlexTable implements AxedListener {
	/**
	 * The AxedArea this belongs to.
	 */
	AxedArea axed;

	/**
	 * Columns of the table
	 */
	public static final int COL_ID   = 1;
	public static final int COL_POS  = 2;
	public static final int COL_TYPE = 3;
	public static final int COL_TEXT = 4;
	public static final int COLS_MAX = 4;

	/**
	 * Constructor 
	 */
	public UndoViewer(AxedArea axed) {
		super();
		this.axed = axed;
		prepareCell(0, 3);
		setText(0, COL_ID,   "ID");
		setText(0, COL_POS,  "Pos");
		setText(0, COL_TYPE, "Type");
		setText(0, COL_TEXT, "Text");
	}

	/**
	 * Handles events from the axed widget.
	 */
	public void onAxedEvent(AxedEvent event) {
		switch (event.type) {
		case AxedEvent.CLEARUNDOREDOSTACK :
		case AxedEvent.INSERT_CHAR :
		case AxedEvent.INSERT_TEXT :
		case AxedEvent.JOIN_LINE :
		case AxedEvent.REMOVE_CHAR :
		case AxedEvent.REMOVE_TEXT :
		case AxedEvent.SPLIT_LINE :
		case AxedEvent.UNDO :
			rebuildTable();
			return;
		default:
			return;
		}
	}

//privates:
	/**
	 * returns the text description of a undo type
	 */
	private String getUndoTypeName(int type) {
		switch (type) {
		case UndoBuffer.DELTEXT     : return "deltext";
		case UndoBuffer.INSTEXT     : return "instext";
		case UndoBuffer.JOINLINE    : return "joinline";
		case UndoBuffer.REMOVECHARS : return "removechars";
		case UndoBuffer.SPLITLINE   : return "splitline";
		case UndoBuffer.TEXT        : return "write text";
		default : 
			// TODO throw 
			assert false;
			return "";
		}
	}

	/**
 	 * rebuilds the bar.
 	 */
	public void rebuildTable() {
		UndoManager um = axed.getUndoManager();
		Stack us = um.getUndoStack();
		
		while(getRowCount() > 1) {
			removeRow(1);
		}

		for (int i = 0; i < us.size(); i++) {
			UndoBuffer ub = (UndoBuffer) us.get(i);
			int r = i + 1;
			prepareCell(r, 4);
			setText(r, COL_ID, "" + ub.atomicID);
			getCellFormatter().setHorizontalAlignment(r, 2, HasHorizontalAlignment.ALIGN_RIGHT);
			if (ub.type == UndoBuffer.SPLITLINE) {
				setText(r, COL_POS, "" + (ub.p1.line + 1));
			} else {
				setText(r, COL_POS, "" + (ub.p1.line + 1) + ":" + ub.p1.col);
			}
			setText(r, COL_TYPE, getUndoTypeName(ub.type));
			if (ub.type == UndoBuffer.SPLITLINE || ub.type == UndoBuffer.JOINLINE) {
				setHTML(r, COL_TEXT, "");
			} else {
				setHTML(r, COL_TEXT, "\"" + ub.getText().replaceAll(" ", "&nbsp;") + "\"");
			}
		}
	}
}
